package com.sukaiyi.leetcode._42trapping_rain_water;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
 * @author sukaiyi
 * @date 2020/05/06
 * @see <a href="https://leetcode-cn.com/problems/trapping-rain-water">题目地址</a>
 */
public class Solution {

    @ParameterizedTest
    @MethodSource("commonParamGenerator")
    public void test(int expected, int[] data) {
        assertEquals(expected, trap(data));
    }

    static Stream<Arguments> commonParamGenerator() {
        return Stream.of(
                Arguments.of(6, new int[]{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1})
        );
    }

    @ParameterizedTest
    @MethodSource("largeParamGenerator")
    public void largeGraphTest(int expected, int[] data) {
        assertEquals(expected, trap(data));
    }

    static Stream<Arguments> largeParamGenerator() throws IOException {
        try (InputStream is = com.sukaiyi.leetcode._45jump_game_ii.Solution.class.getResourceAsStream("largecase.txt")) {
            int available = is.available();
            byte[] buff = new byte[available];
            int len = is.read(buff, 0, available);
            String content = new String(buff);
            int[] largeCase = Arrays.stream(content.split(",")).mapToInt(Integer::parseInt).toArray();
            return Stream.of(
                    Arguments.of(0, largeCase)
            );
        }
    }

    public int trap(int[] height) {
        if (height.length <= 2) {
            return 0;
        }

        int water = 0;
        for (int i = 1; ; i++) {
            int start = 0, end = height.length - 1;
            for (; start < height.length && height[start] < i; start++) ;
            for (; end >= 0 && height[end] < i; end--) ;
            if (end < 0) {
                break;
            }
            for (int j = start; j <= end; j++) {
                water += height[j] < i ? 1 : 0;
            }
        }
        return water;
    }
}
